package ru.niir.goodfil.ui;

import ru.niir.goodfil.audit.client.AuditService;
import ru.niir.goodfil.audit.service.AuditServiceImpl;
import ru.niir.goodfil.audit.service.DefaultConfiguration;
import ru.niir.goodfil.db.audit.helpers.AuditHelper;
import ru.niir.goodfil.exceptions.GoodfilSecurityException;
import ru.niir.goodfil.exceptions.MailerException;
import ru.niir.goodfil.exceptions.SystemIsOfflineException;
import ru.niir.goodfil.ui.audit.JsfAuditHelper;

import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Map;

public class ErrorBean extends PageBean {
    private String exceptionName;

    private String realStackTrace;

    private String stackTrace;

    private String line;

    public ErrorBean() {
        FacesContext context = FacesContext.getCurrentInstance();
        Map requestMap = context.getExternalContext().getRequestMap();
        Throwable ex = (Throwable) requestMap.get("javax.servlet.error.exception");

        StringWriter writer = new StringWriter();
        PrintWriter pw = new PrintWriter(writer);
        fillStackTrace(ex, pw);
        realStackTrace = writer.toString();

        exceptionName = ex.getClass().getName();

        StringBuilder sb = new StringBuilder();
        String[] strs = realStackTrace.split("\\n");
        sb.append("<b>Stacktrace:</b>");
        for (int i = 0; i < strs.length; i++) {
            if (strs[i].indexOf("at ") != -1) {
                if (strs[i].indexOf("ru.niir") != -1) {
                    line = strs[i];
                    sb.append("<br><span style=\"font-weight:bold;font-size:100%\">" + strs[i] + "</span>");
                } else {
                    sb.append("<br><span style=\"font-weight:normal;font-size:80%\">" + strs[i] + "</span>");
                }
            } else {

                sb.append("<br><span style=\"font-weight:normal;font-size:100%\">" + strs[i] + "</span>");
            }

            if (strs[i].indexOf("Caused by: ") != -1) {
                exceptionName = strs[i].substring(strs[i].indexOf(":") + 2);
            }
        }
        stackTrace = sb.toString();

        if (stackTrace.indexOf(GoodfilSecurityException.class.getName()) != -1) {
            try {
                HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
                response.sendRedirect("SecurityError.jsf");
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (stackTrace.indexOf(SystemIsOfflineException.class.getName()) != -1) {
            try {
                HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
                response.sendRedirect("Offline.html");
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            //  Отправка разработчику письма со стектрейсом
            gf().createIfNotExists("developer.mail", "sazonovkirill@gmail.com", "Электронная почта Администратора системы");
            String developerMail = gf().get("developer.mail");
            String subject = "Goodwill: " + exceptionName;
            String msg = realStackTrace;

            try {
                gf().sendEmailMsg(developerMail, subject, msg);
            } catch (MailerException e) {
                e.printStackTrace();
            }

            //  Протоколирование ошибок
            try {
                AuditHelper auditHelper = new JsfAuditHelper();
                AuditService auditService = new AuditServiceImpl(new DefaultConfiguration());

                auditService.logExceptionEvent(auditHelper.getIp(), auditHelper.getLogin(), exceptionName, realStackTrace);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void fillStackTrace(Throwable ex, PrintWriter pw) {
        if (null == ex) {
            return;
        }

        ex.printStackTrace(pw);
    }

    public String getExceptionName() {
        return exceptionName;
    }

    public String getStackTrace() {
        return stackTrace;
    }

    public String getLine() {
        return line;
    }
}
